package com.ytjj.qmyx.mall.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ytjj.common.constants.CopyWriterConstant;
import com.ytjj.common.constants.QueueConstants;
import com.ytjj.common.constants.SysConfigConstants;
import com.ytjj.common.dto.mqdto.OrderRecordDto;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.service.RedisService;
import com.ytjj.common.utils.CopyWriterConfigUtil;
import com.ytjj.common.utils.OrderUtils;
import com.ytjj.common.utils.SysConfigUtil;
import com.ytjj.qmyx.mall.constants.RedisConstants;
import com.ytjj.qmyx.mall.mapper.OrdersSpecMapper;
import com.ytjj.qmyx.mall.mapper.ProductMapper;
import com.ytjj.qmyx.mall.mapper.ProductSpecMapper;
import com.ytjj.qmyx.mall.model.Orders;
import com.ytjj.qmyx.mall.model.OrdersInfo;
import com.ytjj.qmyx.mall.model.Product;
import com.ytjj.qmyx.mall.model.ProductSpec;
import com.ytjj.qmyx.mall.model.request.CreateOrderRequest;
import com.ytjj.qmyx.mall.model.response.CartProductResponse;
import com.ytjj.qmyx.mall.model.response.ProductResponse;
import com.ytjj.qmyx.mall.model.response.ProductSpecResponse;
import com.ytjj.qmyx.mall.service.CreateOrderService;
import com.ytjj.qmyx.mall.service.OrdersService;
import com.ytjj.qmyx.mall.service.ProductService;
import com.ytjj.qmyx.mall.utils.ProductRecordUtil;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 购物车创建订单的方式
 *
 *
 * @version 1.0
 *
 */
@Service("CART")
@Slf4j
public class OrdersCartServiceImpl implements CreateOrderService<CreateOrderRequest>  {

    @Autowired
    private RedisService redisService;

    @Autowired
    private ProductService productService;

    @Autowired
    private OrdersService ordersService;

    @Resource
    private SysConfigUtil sysConfigUtil;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private ProductSpecMapper productSpecMapper;

    @Resource
    private CopyWriterConfigUtil copyWriterConfigUtil;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private OrdersSpecMapper ordersSpecMapper;
    @Override
    @Transactional
    public Integer createOrder(CreateOrderRequest request) {

        // 购物车创建订单
        String[] carts = request.getCartNo();
        // 从缓存中取出购物车信息，并且删除
        List<CartProductResponse> responses = Arrays.asList(carts).stream()
                .map(item -> {
                    String json = redisService.getMapString(RedisConstants.CART_KEY + request.getUserId(), item);
                    CartProductResponse cartResponse = JSONObject.parseObject(json, CartProductResponse.class);
                    redisService.delete(RedisConstants.CART_KEY + request.getUserId(), item);
                    return cartResponse;
                })
                .collect(Collectors.toList());
        BigDecimal realTotalMoney = new BigDecimal(0);
        BigDecimal goodsMoney = new BigDecimal(0);
        // 计算商品总价格
        for(CartProductResponse item : responses){
            ProductSpec productSpec = productService.getProductSpecById(request.getProductSpecId());
            ProductResponse product = productService.getProductById(productSpec.getProductId(),request.getPageSourceV2());
            // 判断库存是否存在
            if (Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.IS_STOCE_VERIFY)) > 0 && product.getStock() <= 0) {
                throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.INSUFFICIENT_STOCK));
            }
            realTotalMoney = realTotalMoney.add(productSpec.getPrice());
            goodsMoney = goodsMoney.add(product.getOriginalPrice());
        }
        //拆单
//        String orderParentNo = createOrderByCartNo(responses, request);

        // 主订单
        Orders orders = ordersService.saveOrders(request.getUserId(), request.getTel(),
                goodsMoney.setScale(2, BigDecimal.ROUND_UP),
                realTotalMoney.setScale(2, BigDecimal.ROUND_UP),
                request.getOrderSource(),request.getChannel(),0);
        // 订单明细
        responses.stream().map(item -> {
            ProductSpec productSpec = productService.getProductSpecById(request.getProductSpecId());
            if (Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.IS_STOCE_VERIFY)) > 0 && productSpec.getStock() <= 0) {
                throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.INSUFFICIENT_STOCK));
            }
            ProductResponse product = productService.getProductById(productSpec.getProductId(),request.getPageSourceV2());
            OrdersInfo ordersInfo = ordersService.saveOrdersInfo(orders.getId(), product.getId(), product.getProductName(), product.getProductImg(),
                    productSpec.getPrice(), productSpec.getOriginalPrice(), product.getWarehouse(), product.getWarehouseName(),
                    product.getWarehouseRule(), request.getSpecialId(), productSpec.getSkuSpec(), product.getBankerId(),
                    productSpec.getId(), null, null, null, null,product.getDescr(),
                    0,request.getPageSourceV2(),null,1,0, productSpec.getCostPrice(), productSpec.getThreeSkuId(),1,"",null);
            try {
                // 记录订单规格信息
                ProductSpec productSpecs = ordersSpecMapper.selectOrderSpec(request.getProductSpecId());
                ordersSpecMapper.insertOrderSpec(productSpecs.getSkuSpec(),orders.getId(),productSpecs.getPrice(),productSpecs.getOriginalPrice(),productSpecs.getCostPrice());
            }catch (Exception e){
                log.error("发送到rabbitmq错误",e);
            }

            return ordersInfo;
        }).collect(Collectors.toList());
        return orders.getId();
    }

    @Override
    public Integer cartCreateOrder(CreateOrderRequest request) {
        return null;
    }

    /**
     * 拆单
     * @param responses
     * @return
     */
    private String createOrderByCartNo(List<CartProductResponse> responses, CreateOrderRequest request) {
        //根据bankerId分组
        Map<Integer, List<CartProductResponse>> groupMap =
            responses.stream().collect(Collectors.groupingBy(CartProductResponse::getBankerId,Collectors.toList()));
        Set<Integer> integers = groupMap.keySet();
//        List<Orders> result = new LinkedList<>();
        String orderParentNo = OrderUtils.getOrderCode(request.getUserId());//组合订单号
        for (Integer bankerId : integers) {
            Map<String, BigDecimal> moneyMap = calculationMoney(bankerId, responses);
            BigDecimal realTotalMoney = moneyMap.get("realTotalMoney");
            BigDecimal goodsMoney = moneyMap.get("money");

            Orders orders = ordersService.saveOrders(request.getUserId(),
                    request.getTel(),
                    goodsMoney.setScale(2, BigDecimal.ROUND_UP),
                    realTotalMoney.setScale(2, BigDecimal.ROUND_UP),
                    request.getOrderSource(),
                    request.getChannel(),
                    0,
                    orderParentNo);

            List<CartProductResponse> products = responses.stream().filter(product -> bankerId.equals(product.getBankerId())).collect(Collectors.toList());
            // 订单明细
            products.stream().map(item -> {
                ProductResponse product = productService.getProductById(item.getId(),request.getPageSourceV2());
                ProductSpecResponse productSpec = productService.getProductSpecInfoById(item.getSpecId());
                if (Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.IS_STOCE_VERIFY)) > 0 && productSpec.getStock() <= 0) {
                    throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.INSUFFICIENT_STOCK));
                }
                OrdersInfo ordersInfo = ordersService.saveOrdersInfo(orders.getId(), product.getId(), product.getProductName(), product.getProductImg(),
                        productSpec.getPrice(), product.getOriginalPrice(), product.getWarehouse(), product.getWarehouseName(),
                        product.getWarehouseRule(), request.getSpecialId(), productSpec.getSkuSpec(), product.getBankerId(),
                        productSpec.getId(), null, null, null, null,product.getDescr(),
                        0,request.getPageSourceV2(),null,1,0, productSpec.getCostPrice(),request.getProductSum());
                try {
                    // 记录订单规格信息
                    ProductSpec productSpecs = ordersSpecMapper.selectOrderSpec(request.getProductSpecId());
                    ordersSpecMapper.insertOrderSpec(productSpecs.getSkuSpec(),orders.getId(),productSpecs.getPrice(),productSpecs.getOriginalPrice(),productSpecs.getCostPrice());
                }catch (Exception e){
                    log.error("发送到rabbitmq错误",e);
                }
                return ordersInfo;
            }).collect(Collectors.toList());

//            result.add(orders);
        }
        return orderParentNo;
    }

    /**
     * 计算订单金额
     * @param bankerId
     * @param responses
     * @return
     */
    private Map<String, BigDecimal> calculationMoney(Integer bankerId, List<CartProductResponse> responses) {
        BigDecimal money = BigDecimal.ZERO;
        BigDecimal realTotalMoney = BigDecimal.ZERO;
        List<CartProductResponse> products = responses.stream().filter(product -> bankerId.equals(product.getBankerId())).collect(Collectors.toList());
        for (CartProductResponse product : products) {
            money = money.add(product.getOriginalPrice());
            realTotalMoney = realTotalMoney.add(product.getPrice());
        }
        Map<String, BigDecimal> result = new HashMap<>();
        result.put("money", money);
        result.put("realTotalMoney", realTotalMoney);
        products = null;
        return result;
    }
}
